home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / text / misc / mpage.lha / mpage / args.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-25  |  18.4 KB  |  511 lines

  1. /*
  2.  * args.c
  3.  */
  4.  
  5. /*
  6.  * mpage:    a program to reduce pages of print so that several pages
  7.  *           of output appear on one printed page.
  8.  *
  9.  * Written by:
  10.  *   ...!uunet!\                       Mark Hahn, Sr Systems Engineer
  11.  *              >pyrdc!mark            Pyramid Technology Corporation
  12.  * ...!pyramid!/                       Vienna, Va    (703)848-2050
  13.  *
  14.  *
  15.  * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
  16.  * Copyright (c) 1994-1997 Marcel J.E. Mol, The Netherlands
  17.  *                    marcel@mesa.nl
  18.  *  
  19.  *     Permission is granted to anyone to make or distribute verbatim
  20.  *     copies of this document as received, in any medium, provided
  21.  *     that this copyright notice is preserved, and that the
  22.  *     distributor grants the recipient permission for further
  23.  *     redistribution as permitted by this notice.
  24.  *
  25.  */
  26.  
  27. #include "mpage.h"
  28. #include <ctype.h>
  29. #include <string.h>
  30.  
  31. /*
  32.  * Function declarations
  33.  */
  34. static char **slice();
  35.  
  36.  
  37.  
  38. int
  39. do_args(argc, argv, envflag)
  40.  int argc;
  41.  char **argv;
  42.  int envflag;
  43. {
  44.     char *optstr;
  45.     int consumed;
  46.     int currarg;
  47.     int opterrors;
  48.  
  49. #define OPTARG()  \
  50.     { consumed = 1; if(*++optstr == '\0') optstr = argv[++currarg]; }
  51.  
  52.     opterrors = 0;
  53.     for (currarg = 1; currarg < argc; currarg++) {
  54.         if (*argv[currarg] != '-') {
  55.             if (envflag)
  56.                 opterrors++;
  57.             break;
  58.         }
  59.         optstr = argv[currarg];
  60.         consumed = 0;
  61.         while (!consumed && *++optstr) {
  62.             switch (*optstr) {
  63.                 default:
  64.                         fprintf(stderr, "%s: unknown option -%c\n",
  65.                                         MPAGE, *optstr);
  66.                         opterrors++;
  67.                         break;
  68.                 case '1':
  69.                         sheetindex = 0;
  70.                         break;
  71.                 case '2':
  72.                         sheetindex = 1;
  73.                         break;
  74.                 case '4':
  75.                         sheetindex = 2;
  76.                         break;
  77.                 case '8':
  78.                         sheetindex = 3;
  79.                         break;
  80.                 case 'a':    /* toggle between accross and updown */
  81.                         sheetorder = sheetorder == LEFTRIGHT ?
  82.                                      UPDOWN : LEFTRIGHT;
  83.                         break;
  84.                 case 'A':    /* A4 sized, european paper */
  85.                         opt_page = PAGE_A4;
  86.                         break;
  87.                 case 'b':     /* base paper type */
  88.                         OPTARG();
  89.                         if (!strcasecmp(optstr, "A4"))
  90.                             opt_page = PAGE_A4;
  91.                         else if (!strcasecmp(optstr, "Letter"))
  92.                             opt_page = PAGE_LETTER;
  93.                         else if (!strcasecmp(optstr, "Legal"))
  94.                             opt_page = PAGE_LEGAL;
  95.                         else if (!strcasecmp(optstr, "A3"))
  96.                             opt_page = PAGE_A3;
  97.                         else
  98.                             fprintf(stderr, "unkown paper type %c\n", *optstr);
  99.                         break;
  100.                 case 'B': {
  101.                         int pb = 0; /* set a default */
  102.  
  103.                         consumed = 1;
  104.                         opt_textbox = 1 - opt_textbox;
  105.                         if (*++optstr == '\0') {
  106.                             break;
  107.                         }
  108.                                 
  109.                         while (*optstr) {
  110.                             int sign;
  111.                             if (*optstr == '-') {
  112.                                 sign = -1;
  113.                                 optstr++;
  114.                             }
  115.                             else
  116.                                 sign = 1;
  117.                             if (isdigit(*optstr)) {
  118.                                 pb = *optstr - '0';
  119.                                 while (*++optstr && isdigit(*optstr))
  120.                                     pb = pb*10 + *optstr - '0';
  121.                             }
  122.                             pb *= sign;
  123.                             switch (*optstr) { 
  124.                                 case 'l': textmargin_left = pb;
  125.                                           break;
  126.                                 case 'r': textmargin_right = pb;
  127.                                           break;
  128.                                 case 't': textmargin_top = pb;
  129.                                           break;
  130.                                 case 'b': textmargin_bottom = pb;
  131.                                           break;
  132.                                 case '\0':textbox.thick = pb;
  133.                                           break;
  134.                                 default:  fprintf(stderr,
  135.                                            "%s: Unknown -B box specifier: %c\n",
  136.                                            MPAGE, *optstr);
  137.                                           break;
  138.                             }
  139.                             if (*optstr)
  140.                                 optstr++;
  141.                         }
  142.                         break;
  143.                     }
  144.                 case 'c':    /* concat pages from different files on sheet */
  145.                         opt_file = 1 - opt_file;
  146.                         break;
  147.                 case 'C':    /* select character definitions */
  148.                         consumed = 1;
  149.                         if (*++optstr) { /* did we get a encoding name ? */
  150.                             if ((charvec_file = (char *) malloc(strlen(libdir) +
  151.                                                                 strlen(optstr) +
  152.                                                                 2)) == NULL) {
  153.                                 perror(optstr);
  154.                                 fprintf(stderr,
  155.                                     "ignoring character encoding definition\n");
  156.                             }
  157.                             else {
  158.                                 (void) strcpy(charvec_file, libdir);
  159.                                 (void) strcat(charvec_file, "/");
  160.                                 (void) strcat(charvec_file, optstr);
  161.                                 opt_encoding = 1;
  162.                             }
  163.                         }
  164.                         else /* no encoding name, toggle default one */
  165.                             opt_encoding = 1 - opt_encoding;
  166.                         break;
  167.                 case 'd':
  168.                         OPTARG();
  169.                         switch (*optstr) {
  170.                 case 'a': opt_input = IN_ASCII; break;
  171.                 case 'p': opt_input = IN_PS; break;
  172.                 default :
  173.                                 fprintf(stderr,
  174.                                         "ignoring input file type -d%c\n",
  175.                                         *optstr);
  176.                 break;
  177.             }
  178.                         break;
  179.                 case 'D':
  180.                         OPTARG();
  181.                         dateformat = optstr;
  182.                         break;
  183.             case 'E': /* GPN. for coli, 2,3(inside) pages */
  184.                     Coli = 2;
  185.                         break;
  186.                 case 'f':    /* fold long lines */
  187.                         opt_fold = 1 - opt_fold;
  188.                         break;
  189.                 case 'F':
  190.                         OPTARG();
  191.                         fontname = optstr;
  192.                         break;
  193.                 case 'h':
  194.                         OPTARG();
  195.                         opt_header = optstr;
  196.                         break;
  197.                 case 'H':
  198.                         opt_mp_header = 1;
  199.                         break;
  200.                 case 'I':
  201.                         OPTARG();
  202.                         opt_indent = atoi(optstr);
  203.                         break;
  204.                 case 'j':    /* Just these sheets */
  205.                         OPTARG();
  206.                         opt_first = isdigit(*optstr) ? 
  207.                                     strtol(optstr, &optstr, 10) : 1;
  208.                         if (*optstr == '-') {
  209.                             if (isdigit(*++optstr))
  210.                                 opt_last = strtol(optstr, &optstr, 10);
  211.                         }
  212.                         else
  213.                             opt_last = MAXINT;
  214.                         if (*optstr == '/' || *optstr == '%')
  215.                             opt_alt = atoi(++optstr);
  216.                         break;
  217.                 case 'l':    /* landscape */
  218.                         sheetaspect = sheetaspect == LANDSCAPE ?
  219.                                       PORTRAIT : LANDSCAPE;
  220.                         break;
  221.                 case 'L':
  222.                         OPTARG();
  223.                         opt_lines = atoi(optstr);
  224.                         break;
  225.                 case 'm': {
  226.                         int sm = 2*DEFAULTSMARGIN; /* set a default */
  227.  
  228.                         consumed = 1;
  229.                         if (*++optstr == '\0') {
  230.                             sheetmargin_left = sm;
  231. #if defined(ALL_MARGINS)
  232.                             sheetmargin_right = sm;
  233.                             sheetmargin_top = sm;
  234.                             sheetmargin_bottom = sm;
  235. #endif
  236.                             break;
  237.                         }
  238.                                 
  239.                         while (*optstr) {
  240.                             int sign;
  241.                             if (*optstr == '-') {
  242.                                 sign = -1;
  243.                                 optstr++;
  244.                             }
  245.                             else
  246.                                 sign = 1;
  247.                             if (isdigit(*optstr)) {
  248.                                 sm = *optstr - '0';
  249.                                 while (*++optstr && isdigit(*optstr))
  250.                                     sm = sm*10 + *optstr - '0';
  251.                             }
  252.                             sm *= sign;
  253.                             switch (*optstr) { 
  254.                                 case 'l': sheetmargin_left = sm;
  255.                                           break;
  256.                                 case 'r': sheetmargin_right = sm;
  257.                                           break;
  258.                                 case 't': sheetmargin_top = sm;
  259.                                           break;
  260.                                 case 'b': sheetmargin_bottom = sm;
  261.                                           break;
  262.                                 case '\0':sheetmargin_left = sm;
  263.                                           sheetmargin_right = sm;
  264.                                           sheetmargin_top = sm;
  265.                                           sheetmargin_bottom = sm;
  266.                                           break;
  267.                                 default:  fprintf(stderr,
  268.                                         "%s: Unknown -m margin specifier: %c\n",
  269.                                         MPAGE, *optstr);
  270.                                           break;
  271.                             }
  272.                             if (*optstr)
  273.                                 optstr++;
  274.                         }
  275.                         break;
  276.                     }
  277.                 case 'M': {
  278.                         int pm = 2*DEFAULTPMARGIN; /* set a default */
  279.  
  280.                         consumed = 1;
  281.                         if (*++optstr == '\0') {
  282.                             pagemargin_left = pm;
  283. #if defined(ALL_MARGINS)
  284.                             pagemargin_right = pm;
  285.                             pagemargin_top = pm;
  286.                             pagemargin_bottom = pm;
  287. #endif
  288.                             break;
  289.                         }
  290.                                 
  291.                         while (*optstr) {
  292.                             int sign;
  293.                             if (*optstr == '-') {
  294.                                 sign = -1;
  295.                                 optstr++;
  296.                             }
  297.                             else
  298.                                 sign = 1;
  299.                             if (isdigit(*optstr)) {
  300.                                 pm = *optstr - '0';
  301.                                 while (isdigit(*++optstr))
  302.                                     pm = pm*10 + *optstr - '0';
  303.                             }
  304.                             pm *= sign;
  305.                             switch (*optstr) { 
  306.                                 case 'l': pagemargin_left = pm;
  307.                                           break;
  308.                                 case 'r': pagemargin_right = pm;
  309.                                           break;
  310.                                 case 't': pagemargin_top = pm;
  311.                                           break;
  312.                                 case 'b': pagemargin_bottom = pm;
  313.                                           break;
  314.                                 case '\0':pagemargin_left = pm;
  315.                                           pagemargin_right = pm;
  316.                                           pagemargin_top = pm;
  317.                                           pagemargin_bottom = pm;
  318.                                           break;
  319.                                 default:  fprintf(stderr,
  320.                                         "%s: Unknown -M margin specifier: %c\n",
  321.                                            MPAGE, *optstr);
  322.                                           break;
  323.                             }
  324.                             if (*optstr)
  325.                                 optstr++;
  326.                         }
  327.                         break;
  328.                     }
  329.                 case 'o':    /* toggle print outlines */
  330.                         opt_outline = 1 - opt_outline;
  331.                         break;
  332.             case 'O': /* GPN. for coli, 4,1(outside) pages */
  333.                     Coli = 1;
  334.                         break;
  335.                 case 'p':    /* pr */
  336.                         opt_pr = 1;
  337.                         consumed = 1;
  338.                         if (*++optstr)
  339.                             prprog = optstr;
  340.                         break;
  341.                 case 'P':    /* Printer */
  342.                         consumed = 1;
  343.                         doprint = 1;
  344.                         if (*++optstr)
  345.                             if (!strcmp(optstr, "-"))
  346.                                 doprint = 0; /* kill MPAGE envvar que setting*/
  347.                             else {
  348.                                 printque = optstr;
  349.                             }
  350.                         break;
  351.                 case 'r':
  352.                         opt_reverse = 1;
  353.                         break;
  354.                 case 'R':    /* reorient  */
  355.                         sheetaspect = LANDSCAPE_PORTRAIT;
  356.                         break;
  357.                 case 's': /* tab Stops */
  358.                         OPTARG();
  359.                         if ((opt_tabstop = atoi(optstr)) < 2)
  360.                             opt_tabstop = DEFAULTTABSTOP;
  361.                         break;
  362.                 case 'S':
  363.                         opt_square = 0;
  364.                         break;
  365.                 case 't':
  366.                         opt_duplex = 1 - opt_duplex;
  367.                         break;
  368.                 case 'T':
  369.                         opt_tumble = 1 - opt_tumble;
  370.                         break;
  371.                 case 'U':    /* Letter sized, US paper */
  372.                         opt_page = PAGE_LETTER;
  373.                         break;
  374.                 case 'v':    /* verbose (print page count) */
  375.                         opt_verbose = 1 - opt_verbose;
  376.                         break;
  377.                 case 'W':
  378.                         OPTARG();
  379.                         opt_width = atoi(optstr);
  380.                         break;
  381.                 case 'x': /* force usage. Could be extended to usagelevel */
  382.                         opterrors = 1;
  383.                         break;
  384.                 case 'X':
  385.                         opt_sheetheader = 1;
  386.                         consumed = 1;
  387.                         if (*++optstr)
  388.                             sheethead = optstr;
  389.                         break;
  390.                 case 'z':
  391.                         OPTARG();
  392.                         printprog = optstr;
  393.                         break;
  394.                 case 'Z':
  395.                         OPTARG();
  396.                         printarg = optstr;
  397.                         break;
  398.  
  399.             }
  400.         }
  401.     }
  402.     set_page();
  403.  
  404.     if (opterrors)
  405.         return -1;
  406.  
  407.     return currarg;
  408.  
  409. } /* do_args */
  410.  
  411.  
  412.  
  413. int
  414. do_env()
  415. {
  416.     int argc;
  417.     char **argv;
  418.     char copy[LINESIZE];
  419.     char *env;
  420.  
  421. #if SPOOLER == ATT_SPOOLER
  422.     if ((env = getenv("LPDEST")) != NULL)
  423. #elif SPOOLER == BSD_SPOOLER
  424.     if ((env = getenv("PRINTER")) != NULL)
  425. #endif
  426.         printque = env;
  427.  
  428.     if ((env = getenv("MPAGE_LIB")) != NULL)
  429.         libdir = env;
  430.  
  431.     if ((env = getenv("MPAGE")) != NULL) {
  432.         strcpy(copy, env);
  433.         argv = slice(copy, &argc);
  434.         if (do_args(argc, argv, 1) < 0) {
  435.             fprintf(stderr, "%s: error in environment \"%s\"\n", MPAGE, env);
  436.             return -1;
  437.         }
  438.     }
  439.  
  440.     return 0;
  441.  
  442. } /* do_env */
  443.  
  444. #define ARGCNT    20
  445.  
  446. char *slc_argv[ARGCNT+1];
  447.  
  448. static char **
  449. slice(string, cntp)
  450.  char *string;
  451.  int *cntp;
  452. {
  453.     int count;
  454.  
  455.     /*
  456.      * mimic the shell for conformity
  457.      */
  458.     slc_argv[0] = MPAGE;
  459.     count = 1;
  460.     /*
  461.      * while there are still characters to be processed
  462.      */
  463.     while (*string && count < ARGCNT) {
  464.         /*
  465.          * skip any leading or leftover white space
  466.          */
  467.         while (*string == ' ')
  468.             string++;
  469.         /*
  470.          * make sure we had more than just white space before
  471.          * we believe we actually have an argument
  472.          */
  473.         if (*string) {
  474.             /*
  475.              * point the next slot in argv to this string
  476.              */
  477.             slc_argv[count++] = string;
  478.             /*
  479.              * and go looking for the end of this string
  480.              * which is delienated by a space or NULL
  481.              */
  482.             while (*string && *string != ' ')
  483.                 string++;
  484.             /*
  485.              * if this not the end of the string, then convert
  486.              * the space into a NULL and move forward one byte.
  487.              * if this is the end of the string, we already have
  488.              * a suitable NULL byte for the string and it also
  489.              * drops us out of all the loops
  490.              */
  491.             if (*string) {
  492.                 *string = 0;
  493.                 string++;
  494.             }
  495.         }
  496.     }
  497.     /*
  498.      * return the count via the integer pointer we were given
  499.      * and put a null pointer into the argv array for conformity
  500.      */
  501.     if (*string && count == ARGCNT)
  502.         fprintf(stderr,
  503.            "%s: to many options in MPAGE environment variable, skipping '%s'\n",
  504.                MPAGE, string);
  505.     slc_argv[count] = 0;
  506.     *cntp = count;
  507.  
  508.     return slc_argv;
  509.  
  510. } /* slice */
  511.